#pragma once
#include <poll.h>
#include "sock.hpp"

namespace ns_pollserver
{
    using namespace ns_sock;
    const u_int16_t PORT = 8080;
    const int NUM = 1024;
    class PollServer
    {
    private:
        u_int16_t _port;
        int _listen_sock;
        struct pollfd pollfds_[NUM];
    public:
        PollServer(u_int16_t port = PORT)
            :_port(port)
            ,_listen_sock(-1)
        {
            for (int i = 0; i < NUM; ++i) {
                pollfds_[i].fd = -1;
                pollfds_[i].events = 0;
                pollfds_[i].revents = 0;
            }
        }
        void InitServer() {
            _listen_sock = Sock::Socket();
            Sock::Bind(_listen_sock, _port);
            Sock::Listen(_listen_sock);
            pollfds_[0].fd = _listen_sock;
            pollfds_[0].events = POLLIN;
            pollfds_[0].revents = 0;
        }
        void HandlerEvents(pollfd pollfds[], int num) {
            for (int i = 0; i < num; ++i) {
                if (-1 == pollfds[i].fd) continue;
                if (pollfds[i].revents & POLLIN) {
                    if (_listen_sock == pollfds[i].fd) {
                        // 有新的套接字到来
                        struct sockaddr_in peer;
                        socklen_t len = sizeof(peer);
                        int sock = accept(_listen_sock, (struct sockaddr*)&peer, &len);
                        if (sock < 0) {
                            std::cout << "accept error" << std::endl;
                            continue;
                        } else {
                            int j = 0;
                            for (j = 0; j < num; ++j) {
                                if (pollfds[j].fd == -1) {
                                    break;
                                }
                            }
                            if (j == num) {
                                std::cout << "fd 已满" << std::endl;
                                close(sock);
                            } else {
                                pollfds[j].fd = sock;
                                pollfds[j].events = POLLIN;
                                pollfds[j].revents = 0;
                            }
                        }
                    } else {
                        // 有数据到来
                        char buffer[1024];
                        int s = recv(pollfds[i].fd, buffer, sizeof(buffer)-1, 0);
                        if (s > 0) {
                            buffer[s] = 0;
                            std::cout << "client say#  " << buffer << std::endl;
                        } else if (s == 0) {
                            std::cout << "对端关闭" << std::endl;
                            close(pollfds[i].fd);
                            pollfds[i].fd = -1;
                            pollfds[i].events = 0;
                            pollfds[i].revents = 0;
                        } else {
                            std::cout << "recv error" << std::endl;
                        }
                    }
                }
            }
        }
        void Loop() {
            int timeout = -1;
            while (true) {
                 int n = poll(pollfds_, NUM, timeout);
                 switch (n)
                 {
                 case 0:
                    std::cout << "超时返回" << std::endl;
                    //  超时
                     break;
                  case -1:
                    std::cout << "出错返回" << std::endl;
                    // 出错
                     break;                
                 default:
                    // std::cout << "select成功" << std::endl;
                     HandlerEvents(pollfds_, NUM);
                     break;
                 }
            }
        }
        ~PollServer() {
            if (_listen_sock >= 0) {
                close(_listen_sock);
            }
        }
    };
} // namespace ns_pollserver
